#!/usr/bin/python3
# ******************************************************************************
# Copyright (c) Huawei Technologies Co., Ltd. 2020-2020. All rights reserved.
# licensed under the Mulan PSL v2.
# You can use this software according to the terms and conditions of the Mulan PSL v2.
# You may obtain a copy of Mulan PSL v2 at:
#     http://license.coscl.org.cn/MulanPSL2
# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR
# PURPOSE.
# See the Mulan PSL v2 for more details.
# Author: DisNight
# Create: 2020-12-28
# ******************************************************************************/
"""

"""
import os
import logging
from src.util.osc_utils import osc_ls_binaries_list
from src.util.osc_utils import get_all_bin_name_list
from src.util.dnf_utils import dnf_download

logging.getLogger().setLevel(logging.INFO)


def perp_download_dir(dir_path, pkg_name, dir_list=["old", "new"]):
    """
    The folder to be saved
    Args:
        dir_path: Folder path
        pkg_name: The package name
        dir_list: Folder

    Returns:
        save_dir: The dictionary to save the folder
    """
    save_dir = {}
    for repo in dir_list:
        repo_path = os.path.join(dir_path, pkg_name, repo)
        try:
            _ = not os.path.exists(repo_path) and os.makedirs(repo_path)
        except Exception as error:
            logging.error("Exception: %s", str(error))
        save_dir[repo] = repo_path
    return save_dir


def download_dnf_rpms(down_dir, bin_list, repos=None):
    """
    Download dnf RPM package
    Args:
        down_dir: Download folder
        bin_list: Binary package list
        repos: repos

    Returns:

    """
    for bin_name in bin_list:
        logging.info("try download [%s] in repo[%s]",
                     bin_name, " ".join(repos) if repos else "default repo")
        dnf_download(down_dir, bin_name, repos)


def get_osc_binaries(pkg_name, obs_proj):
    """
    get osc binaries
    Args:
        pkg_name: The package name
        obs_proj: obs project

    Returns:

    """
    out_info, returncode = osc_ls_binaries_list(obs_proj, pkg_name)
    return get_all_bin_name_list(out_info.split())


def download_get_src2binmap(save_dir, pkg_list, obs_prj):
    """
    download get src to bin map
    Args:
        save_dir: save_dir
        pkg_list: pkg_list
        obs_prj: obs_prj

    Returns:
        src2bin_map
    """
    src2bin_map = {}
    for repo in pkg_list:
        if not repo:
            continue
        src_name = repo.strip().split("src-openEuler/")[-1]
        src2bin_map[src_name] = []
        save_dir_list = perp_download_dir(save_dir, src_name)
        currnet_download_path = os.path.join(save_dir, src_name, "obs")
        bin_list = download_osc_rpms(currnet_download_path, src_name, obs_prj)
        download_dnf_rpms(save_dir_list["old"], bin_list)
        src2bin_map[src_name].extend(bin_list)
    return src2bin_map


def get_bin_rpmlist(pkg_list, obs_prj="openEuler:20.03:LTS"):
    """
    use osc getbinaries to download all bin rpms to get all bin rpms for each pkg
    default download dir: /tmp/update-package/download/pkgname/tmpd
    Args:
        pkg_list: The package list
        obs_prj: obs project

    Returns:
        pkg2bin_map: Binary packet dictionary
    """
    pkg2bin_map = {}
    for pkg in pkg_list:
        if not pkg:
            continue
        pkg_name = pkg.strip().split("src-openEuler/")[-1]
        pkg2bin_map[pkg_name] = []
        bin_list = get_osc_binaries(pkg_name, obs_prj)
        logging.info("pkg:[%s] bin_rpms:[%s]", pkg_name, ", ".join(bin_list))
        pkg2bin_map[pkg_name].extend(bin_list)
    return pkg2bin_map


def download_all_pkgbin(save_dir, pkg2bin_map, old_repos, new_repos):
    """
    use dnf cmd download all packages' bin rpms
    Args:
        save_dir: save dir
        pkg2bin_map: Binary packet dictionary
        old_repos: old repos
        new_repos: new repos

    Returns:

    """
    for pkg_name in pkg2bin_map:
        paths = perp_download_dir(save_dir, pkg_name, ["old", "new"])
        download_dnf_rpms(paths["old"], pkg2bin_map[pkg_name], old_repos)
        download_dnf_rpms(paths["new"], pkg2bin_map[pkg_name], new_repos)


def download_required_rpm(save_dir, required_list, repos=None):
    """
    download required rpm
    Args:
        save_dir: save dir
        required_list: required list
        repos: repos

    Returns:

    """
    _ = not os.path.exists(save_dir) and os.makedirs(save_dir)
    for bin_name in required_list:
        logging.info("download required rpm: [%s] in repo[%s]",
                     bin_name, " ".join(repos) if repos else "default repo")
        dnf_download(save_dir, bin_name, repos)
